﻿using HtmlAgilityPack;
using Newtonsoft.Json;
using OznerOA.Utils;
using OznerOA.Common;
using System;
using OznerOA.Model;

namespace OznerOA.BLL
{
    public class BaseBLL
    {
        protected LogBLL logBLL = new LogBLL(typeof(BaseBLL).Name,string.Empty);
        #region rest请求部分
        protected BaseResult<T> RestPostHtml<T>(string URL)
        {
            return RestRequestHtml<T>(URL, "POST");
        }
        protected BaseResult<T> RestGetHtml<T>(string URL)
        {
            return RestRequestHtml<T>(URL, "GET");
        }

        protected BaseResult<T> GetResult<T>(Code code,string Message,string logTip)
        {
            if (!string.IsNullOrEmpty(logTip))
                logBLL.Error(logTip);
            return new BaseResult<T>()
            {
                Code = code,
                Message = Message
            };
        }

        protected BaseResult<T> RestRequestHtml<T>(string URL,string Method)
        {
            BaseResult<T> br = new BaseResult<T>();
            //处理url
            if (!URL.StartsWith("http"))
            {
                if (URL.StartsWith("/"))
                {
                    URL = ConfigModel.BaseUrl + URL;
                }
                else
                {
                    URL = ConfigModel.BaseUrl + "/" + URL;
                }
            }
            HttpBaseResult hbr = null;
            if(Method == "GET")
            {
                hbr = HttpRestHelper.HttpGetResponse(URL, ConfigModel.Cookies);
            }
            if (Method == "POST")
            {
                hbr = HttpRestHelper.HttpPostResponse(URL, ConfigModel.Cookies);
            }
            br.HttpBaseResult = hbr;
            if(hbr.Code == 200)
            {
                if (hbr.ContentType.Contains("text/html"))
                {
                    //HtmlDocument doc = new HtmlDocument();
                    //doc.Load(hbr.Html);
                    //br.OtherInfo = doc;
                }
            }else
            {
                br.Code = Code.NULL;
                br.Message = string.Format("网络连接失败:{0}\r\n{1}", hbr.Code, hbr.Description);
            }
            return br;
        }

        #endregion


        #region 解析http地址
        /// <summary>
        /// 解析例如"/abc/ddd?a=1&b=2"的地址
        /// </summary>
        protected HttpAddress ParseAddress(string address)
        {
            HttpAddress ha = new HttpAddress();
            ha.Address = address;
            //首先判断是否http/https开头
            if (address.StartsWith("http://"))
            {
                ha.Protocal = "HTTP";
                address = address.Replace("http://", "");
            }
            if (address.StartsWith("https://"))
            {
                ha.Protocal = "HTTPs";
                address = address.Replace("https://", "");
            }
            //去掉协议之后，判断是否以/开头，并去掉/
            if (address.StartsWith("/"))
            {
                address = address.Substring(1, address.Length - 1);
            }
            //处理参数
            if (address.Contains("?"))
            {
                string[] t = address.Split('?');
                address = t[0];
                string[] ps = t[1].Split('&');
                foreach (string p in ps)
                {
                    string[] kv = p.Split('=');
                    ha.Params.Add(kv[0], kv[1]);
                }
            }
            //处理models
            if (address.Contains("/"))
            {
                string[] models = address.Split('/');
                foreach (string model in models)
                {
                    ha.Models.Add(model);
                }
                ha.Page = models[models.Length - 1];
                ha.Models.RemoveAt(ha.Models.Count - 1);
            }
            else
            {
                ha.Page = address;
            }
            return ha;
        }
        #endregion















        //判断是否登录页面
        public bool IsLogin(HttpBaseResult hbr)
        {
            return hbr.Html.Contains("try{top.location.href='/login/Login.jsp");
        }

        /// <summary>
        /// 获取未登录的HTML数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uRL"></param>
        /// <returns></returns>
        protected BaseResult<T> PostNoLoginedHtml<T>(string URL, string postdata)
        {
            return GetNoLoginedInfo<T>(URL, "POST", "HTML", postdata);
        }
        /// <summary>
        /// 获取未登录的json数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uRL"></param>
        /// <returns></returns>
        protected BaseResult<T> PostNoLoginedJson<T>(string URL, string postdata)
        {
            return GetNoLoginedInfo<T>(URL, "POST", "JSON", postdata);
        }
        /// <summary>
        /// 获取已经登录的json数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uRL"></param>
        /// <returns></returns>
        protected BaseResult<T> PostLoginedJson<T>(string URL, string postdata)
        {
            return GetLoginedInfo<T>(URL, "POST", "JSON", postdata);
        }
        /// <summary>
        /// 获取已经登录的HTML数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uRL"></param>
        /// <returns></returns>
        protected BaseResult<T> PostLoginedHtml<T>(string URL, string postdata)
        {
            return GetLoginedInfo<T>(URL, "POST", "HTML", postdata);
        }
        /// <summary>
        /// 获取已经登录的页面的HtmlDocument
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected BaseResult<T> GetLoginedDocument<T>(string URL)
        {
            return GetLoginedInfo<T>(URL, "GET", "HTML", null);
        }
        private BaseResult<T> GetLoginedInfo<T>(string URL, string method, string type, string postdata)
        {
            return GetInfo<T>(URL, method, type, postdata, true);
        }
        private BaseResult<T> GetNoLoginedInfo<T>(string URL, string method, string type, string postdata)
        {
            return GetInfo<T>(URL, method, type, postdata, false);
        }
        private BaseResult<T> GetInfo<T>(string URL, string method, string type, string postdata, bool isValidateLogin)
        {
            //处理url
            if (!URL.StartsWith("http"))
            {
                if (URL.StartsWith("/"))
                {
                    URL = ConfigModel.BaseUrl + URL;
                }
                else
                {
                    URL = ConfigModel.BaseUrl + "/" + URL;
                }
            }
            BaseResult<T> bsv = new BaseResult<T>();
            HttpBaseResult hbr = null;
            method = method.ToUpper();
            type = type.ToUpper();
            if (method == "GET")
            {
                if (type == "HTML")
                {
                    hbr = HttpHelper.HttpGetHtml(URL, ConfigModel.Cookies);
                }
                if (type == "JSON")
                {
                    hbr = HttpHelper.HttpGetJson(URL, ConfigModel.Cookies);
                }
            }
            if (method == "POST")
            {
                if (type == "HTML")
                {
                    hbr = HttpHelper.HttpPostHtml(URL, ConfigModel.Cookies, postdata);
                }
                if (type == "JSON")
                {
                    hbr = HttpHelper.HttpPostJson(URL, ConfigModel.Cookies, postdata);
                }
            }
            bsv.HttpBaseResult = hbr;
            //判断结果
            if (hbr.Code == 200 && !string.IsNullOrEmpty(hbr.Html))
            {
                if (type.ToUpper() == "HTML")
                {
                    HtmlDocument doc = new HtmlDocument();
                    doc.LoadHtml(hbr.Html);
                    if (isValidateLogin && IsLogin(hbr))
                    {
                        bsv.Code = Code.LOGOUT;
                        bsv.Message = "您已下线，请先登录!";
                    }
                    else
                    {
                        bsv.Code = Code.OK;
                        bsv.OtherInfo = doc;
                    }
                }
                else
                {
                    bsv.Code = Code.OK;
                    bsv.Object = JsonConvert.DeserializeObject<T>(hbr.Html);
                }
            }
            else
            {
                bsv.Message = "Code=" + hbr.Code + ";\r\n" + hbr.Description;
            }
            return bsv;

        }
    }
}
